#pragma once
#include"hashtable.h"
using namespace HashBucket;

namespace My_unordered_map
{
	template<class K, class V>
	struct MapKeyOfT 
	{
	public:
		const K& operator()(const pair<K, V>& kv) 
		{
			return kv.first;
		}
	};

	template<class K, class V, class Hash = HashFunc<K>> 
	class My_unordered_map
	{
	public:
		typedef pair<const K, V> PKV;
		typedef typename::MY_HashBucket<K, PKV, MapKeyOfT<K, V>, Hash>::iterator iterator;
		typedef typename::MY_HashBucket<K, PKV, MapKeyOfT<K, V>, Hash>::const_iterator const_iterator;
		//iterator
		iterator begin() 
		{
			return MyMap.begin();
		}
		
		iterator end() 
		{
			return MyMap.end();
		}

		const_iterator begin() const 
		{
			return MyMap.begin();
		}
		
		const_iterator end() const 
		{
			return MyMap.end();
		}


		pair<iterator, bool> insert(const pair<K, V>& kv)
		{
			return MyMap.insert(kv);
		}

		//operator[]
		V& operator[](const K& key) 
		{
			pair<iterator, bool> ret = insert({ key, V() });
			return ret.first->second;
		}

		

	private:
		MY_HashBucket<K, PKV, MapKeyOfT<K, V>, Hash> MyMap;
	};

	void test_map() 
	{
		My_unordered_map<int, int> mp;
		mp.insert({ 71, 16 });
		mp.insert({ 51, 145 });
		mp.insert({ 111, 31 });
		mp.insert({ 122, 71 });
		mp.insert({ 18, 71 });
		mp.insert({ 16, 81 });
		mp.insert({ 14, 411 });

		auto it = mp.begin();
		while (it != mp.end()) 
		{
			cout << (*it).first << " ";
			++it;
		}
		cout << endl;

		cout << mp[2] << endl;
		cout << mp[51] << endl;
	}

}